From 85774d2bcdf05bf5b8b94a866da2840cf66f9a71 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 19 Feb 2021 22:07:48 +0000 Subject: [PATCH] docs: Update the "Getting Started" page Drop the Pandoc stuff, add the gi-docgen links, and remove a stray docbook element. --- docs/reference/gtk/getting_started.md | 327 ++++++++++++++------------ 1 file changed, 172 insertions(+), 155 deletions(-) diff --git a/docs/reference/gtk/getting_started.md b/docs/reference/gtk/getting_started.md index b10dd1e572..9daba55a23 100644 --- a/docs/reference/gtk/getting_started.md +++ b/docs/reference/gtk/getting_started.md @@ -30,7 +30,7 @@ window. Create a new file with the following content named `example-0.c`. -``` {.c source=examples/window-default.c } +```c #include static void @@ -64,7 +64,7 @@ main (int argc, You can compile the program above with GCC using: ``` -gcc `pkg-config --cflags gtk4` -o example-0 example-0.c `pkg-config --libs gtk4` +gcc $( pkg-config --cflags gtk4 ) -o example-0 example-0.c $( pkg-config --libs gtk4 ) ``` For more information on how to compile a GTK application, please @@ -78,49 +78,51 @@ Even if GTK installs multiple header files, only the top-level `gtk/gtk.h` header can be directly included by third-party code. The compiler will abort with an error if any other header is directly included. -In a GTK application, the purpose of the main() function is to create a -GtkApplication object and run it. In this example a GtkApplication pointer -named `app` is declared and then initialized using gtk_application_new(). +In a GTK application, the purpose of the `main()` function is to create a +[class@Gtk.Application] object and run it. In this example a +[class@Gtk.Application] pointer named `app` is declared and then initialized +using `gtk_application_new()`. -When creating a GtkApplication, you need to pick an application identifier -(a name) and pass it to gtk_application_new() as parameter. For this example -`org.gtk.example` is used. For choosing an identifier for your application, see -[this guide](https://wiki.gnome.org/HowDoI/ChooseApplicationID). Lastly, -gtk_application_new() takes GApplicationFlags as input for your application, -if your application would have special needs. +When creating a [class@Gtk.Application], you need to pick an application +identifier (a name) and pass it to [ctor@Gtk.Application.new] as parameter. For +this example `org.gtk.example` is used. For choosing an identifier for your +application, see [this guide](https://wiki.gnome.org/HowDoI/ChooseApplicationID). +Lastly, [ctor@Gtk.Application.new] takes `GApplicationFlags` as input +for your application, if your application would have special needs. Next the [activate signal](https://wiki.gnome.org/HowDoI/GtkApplication) is -connected to the activate() function above the main() function. The `activate` -signal will be emitted when your application is launched with g_application_run() -on the line below. The g_application_run() call also takes as arguments the +connected to the activate() function above the `main()` function. The `activate` +signal will be emitted when your application is launched with `g_application_run()` +on the line below. The `g_application_run()` call also takes as arguments the command line arguments (the `argc` count and the `argv` string array). Your application can override the command line handling, e.g. to open files passed on the commandline. -Within g_application_run() the activate signal is sent and we then proceed +Within `g_application_run()` the activate signal is sent and we then proceed into the activate() function of the application. This is where we construct our GTK window, so that a window is shown when the application is launched. -The call to gtk_application_window_new() will create a new GtkWindow and -store it inside the `window` pointer. The window will have a frame, a title -bar, and window controls depending on the platform. - -A window title is set using gtk_window_set_title(). This function takes a -GtkWindow* pointer and a string as input. As our `window` pointer is a -GtkWidget pointer, we need to cast it to GtkWindow*. But instead of casting -`window` via `(GtkWindow*)`, `window` can be cast using the macro -`GTK_WINDOW()`. `GTK_WINDOW()` will check if the pointer is an instance of -the GtkWindow class, before casting, and emit a warning if the check fails. -More information about this convention can be found -[here](https://developer.gnome.org/gobject/stable/gtype-conventions.html). - -Finally the window size is set using gtk_window_set_default_size() -and the window is then shown by GTK via gtk_widget_show(). - -When you close the window, by for example pressing the X, the g_application_run() -call returns with a number which is saved inside an integer variable named -`status`. Afterwards, the GtkApplication object is freed from memory with -g_object_unref(). Finally the status integer is returned and the application -exits. +The call to [ctor@Gtk.ApplicationWindow.new] will create a new +[class@Gtk.ApplicationWindow] and store it inside the `window` pointer. The +window will have a frame, a title bar, and window controls depending on the +platform. + +A window title is set using [`method@Gtk.Window.set_title`]. This function +takes a `GtkWindow` pointer and a string as input. As our `window` pointer +is a `GtkWidget` pointer, we need to cast it to `GtkWindow`; instead of +casting `window` via a typical C cast like `(GtkWindow*)`, `window` can be +cast using the macro `GTK_WINDOW()`. `GTK_WINDOW()` will check if the +pointer is an instance of the `GtkWindow` class, before casting, and emit a +warning if the check fails. More information about this convention can be +found [here](https://developer.gnome.org/gobject/stable/gtype-conventions.html). + +Finally the window size is set using [`method@Gtk.Window.set_default_size`] +and the window is then shown by GTK via [method@Gtk.Widget.show]. + +When you close the window, by (for example) pressing the X button, the +`g_application_run()` call returns with a number which is saved inside an +integer variable named `status`. Afterwards, the `GtkApplication` object is +freed from memory with `g_object_unref()`. Finally the status integer is +returned and the application exits. While the program is running, GTK is receiving _events_. These are typically input events caused by the user interacting with your program, but also things @@ -139,11 +141,11 @@ this example is called *Hello, World*. ![Hello, world](hello-world.png) -### Hello World in C {#gtk-getting-started-hello-world} +### Hello World in C Create a new file with the following content named `example-1.c`. -``` {.c source=examples/hello-world.c } +```c #include static void @@ -196,43 +198,44 @@ main (int argc, You can compile the program above with GCC using: ``` -gcc `pkg-config --cflags gtk4` -o example-1 example-1.c `pkg-config --libs gtk4` +gcc $( pkg-config --cflags gtk4 ) -o example-1 example-1.c $( pkg-config --libs gtk4 ) ``` -As seen above, example-1.c builds further upon example-0.c by adding a -button to our window, with the label "Hello World". Two new GtkWidget +As seen above, `example-1.c` builds further upon `example-0.c` by adding a +button to our window, with the label "Hello World". Two new `GtkWidget` pointers are declared to accomplish this, `button` and `box`. The box -variable is created to store a GtkBox, which is GTK's way of controlling -the size and layout of buttons. +variable is created to store a [class@Gtk.Box], which is GTK's way of +controlling the size and layout of buttons. -The GtkBox is created with gtk_box_new() which takes a GtkOrientation -enum as parameter. The buttons which this box will contain can either be laid -out horizontally or vertically. This does not matter in this particular case, -as we are dealing with only one button. After initializing box with the newly -created GtkBox, the code adds the box widget to the window widget using -gtk_window_set_child(). +The `GtkBox` widget is created with [ctor@Gtk.Box.new], which takes a +[enum@Gtk.Orientation] enumeration value as parameter. The buttons which +this box will contain can either be laid out horizontally or vertically. +This does not matter in this particular case, as we are dealing with only +one button. After initializing box with the newly created `GtkBox`, the code +adds the box widget to the window widget using [`method@Gtk.Window.set_child`]. Next the `button` variable is initialized in similar manner. -gtk_button_new_with_label() is called which returns a GtkButton to be -stored in `button`. Afterwards `button` is added to our `box`. - -Using g_signal_connect(), the button is connected to a function in our app called -print_hello(), so that when the button is clicked, GTK will call this function. -As the print_hello() function does not use any data as input, NULL is passed -to it. print_hello() calls g_print() with the string "Hello World" which will +[`ctor@Gtk.Button.new_with_label`] is called which returns a +[class@Gtk.Button] to be stored in `button`. Afterwards `button` is added to +our `box`. + +Using `g_signal_connect()`, the button is connected to a function in our app called +`print_hello()`, so that when the button is clicked, GTK will call this function. +As the `print_hello()` function does not use any data as input, `NULL` is passed +to it. `print_hello()` calls `g_print()` with the string "Hello World" which will print Hello World in a terminal if the GTK application was started from one. -After connecting print_hello(), another signal is connected to the "clicked" -state of the button using g_signal_connect_swapped(). This functions is similar -to a g_signal_connect() with the difference lying in how the callback function -is treated. g_signal_connect_swapped() allows you to specify what the callback +After connecting `print_hello()`, another signal is connected to the "clicked" +state of the button using `g_signal_connect_swapped()`. This functions is similar +to a `g_signal_connect()`, with the difference lying in how the callback function +is treated; `g_signal_connect_swapped()` allows you to specify what the callback function should take as parameter by letting you pass it as data. In this case -the function being called back is gtk_window_destroy() and the `window` pointer +the function being called back is [method@Gtk.Window.destroy] and the `window` pointer is passed to it. This has the effect that when the button is clicked, the whole -GTK window is destroyed. In contrast if a normal g_signal_connect() were used -to connect the "clicked" signal with gtk_window_destroy(), then the function +GTK window is destroyed. In contrast if a normal `g_signal_connect()` were used +to connect the "clicked" signal with [method@Gtk.Window.destroy], then the function would be called on `button` (which would not go well, since the function expects -a GtkWindow as argument). +a `GtkWindow` as argument). More information about creating buttons can be found [here](https://wiki.gnome.org/HowDoI/Buttons). @@ -256,11 +259,11 @@ arrange several buttons: ![Grid packing](grid-packing.png) -### Packing buttons {#gtk-getting-started-grid-packing} +### Packing buttons Create a new file with the following content named `example-2.c`. -``` {.c source=examples/grid-packing.c } +```c #include static void @@ -335,7 +338,7 @@ main (int argc, You can compile the program above with GCC using: ``` -gcc `pkg-config --cflags gtk4` -o example-2 example-2.c `pkg-config --libs gtk4` +gcc $( pkg-config --cflags gtk4 ) -o example-2 example-2.c $( pkg-config --libs gtk4 ) ``` ## Custom Drawing @@ -343,14 +346,14 @@ gcc `pkg-config --cflags gtk4` -o example-2 example-2.c `pkg-config --libs gtk4` Many widgets, like buttons, do all their drawing themselves. You just tell them the label you want to see, and they figure out what font to use, draw the button outline and focus rectangle, etc. Sometimes, it is necessary to -do some custom drawing. In that case, a GtkDrawingArea might be the right +do some custom drawing. In that case, a [class@Gtk.DrawingArea] might be the right widget to use. It offers a canvas on which you can draw by setting its draw function. -The contents of a widget often need to be partially or fully redrawn, -e.g. when another window is moved and uncovers part of the widget, or -when the window containing it is resized. It is also possible to explicitly -cause a widget to be redrawn, by calling gtk_widget_queue_draw(). GTK takes +The contents of a widget often need to be partially or fully redrawn, e.g. +when another window is moved and uncovers part of the widget, or when the +window containing it is resized. It is also possible to explicitly cause a +widget to be redrawn, by calling [`method@Gtk.Widget.queue_draw`]. GTK takes care of most of the details by providing a ready-to-use cairo context to the draw function. @@ -360,11 +363,11 @@ demonstrates input event handling with event controllers. ![Drawing](drawing.png) -### Drawing in response to input {#gtk-getting-started-drawing} +### Drawing in response to input Create a new file with the following content named `example-4.c`. -``` {.c source=examples/drawing.c } +```c #include /* Surface to store current scribbles */ @@ -557,7 +560,7 @@ main (int argc, You can compile the program above with GCC using: ``` -gcc `pkg-config --cflags gtk4` -o example-4 example-4.c `pkg-config --libs gtk4` +gcc $( pkg-config --cflags gtk4 ) -o example-4 example-4.c $( pkg-config --libs gtk4 ) ``` ## Building user interfaces @@ -568,13 +571,13 @@ cumbersome, and making changes becomes next to impossible. Thankfully, GTK supports the separation of user interface layout from your business logic, by using UI descriptions in an -XML format that can be parsed by the GtkBuilder class. +XML format that can be parsed by the [class@Gtk.Builder] class. ### Packing buttons with GtkBuilder Create a new file with the following content named `example-3.c`. -``` {.c source=examples/builder.c } +```c #include #include @@ -638,7 +641,7 @@ main (int argc, Create a new file with the following content named `builder.ui`. -``` {.xml source=examples/builder.ui } +```xml @@ -682,24 +685,24 @@ Create a new file with the following content named `builder.ui`. You can compile the program above with GCC using: ``` -gcc `pkg-config --cflags gtk4` -o example-3 example-3.c `pkg-config --libs gtk4` +gcc $( pkg-config --cflags gtk4 ) -o example-3 example-3.c $( pkg-config --libs gtk4 ) ``` -Note that GtkBuilder can also be used to construct objects that are +Note that `GtkBuilder` can also be used to construct objects that are not widgets, such as tree models, adjustments, etc. That is the reason -the method we use here is called gtk_builder_get_object() and returns -a GObject* instead of a GtkWidget*. +the method we use here is called [`method@Gtk.Builder.get_object`] and returns +a `GObject` instead of a `GtkWidget`. -Normally, you would pass a full path to gtk_builder_add_from_file() to +Normally, you would pass a full path to [`method@Gtk.Builder.add_from_file`] to make the execution of your program independent of the current directory. A common location to install UI descriptions and similar data is `/usr/share/appname`. It is also possible to embed the UI description in the source code as a -string and use gtk_builder_add_from_string() to load it. But keeping the +string and use [`method@Gtk.Builder.add_from_string`] to load it. But keeping the UI description in a separate file has several advantages: It is then possible to make minor adjustments to the UI without recompiling your program, and, -more importantly, graphical UI editors such as [glade](http://glade.gnome.org) +more importantly, graphical UI editors such as [Glade](http://glade.gnome.org) can load the file and allow you to create and modify your UI by point-and-click. ## Building applications @@ -708,41 +711,45 @@ An application consists of a number of files: The binary : This gets installed in `/usr/bin`. + A desktop file : The desktop file provides important information about the application to the desktop shell, such as its name, icon, D-Bus name, commandline to launch it, etc. It is installed in `/usr/share/applications`. + An icon : The icon gets installed in `/usr/share/icons/hicolor/48x48/apps`, where it -will be found regardless of the current theme. + will be found regardless of the current theme. + A settings schema : If the application uses GSettings, it will install its schema in - `/usr/share/glib-2.0/schemas`, so that tools like dconf-editor can find it. + `/usr/share/glib-2.0/schemas`, so that tools like dconf-editor can find it. + Other resources : Other files, such as GtkBuilder ui files, are best loaded from resources stored in the application binary itself. This eliminates the need for most of the files that would traditionally be installed in an application-specific location in `/usr/share`. -GTK includes application support that is built on top of GApplication. In this +GTK includes application support that is built on top of `GApplication`. In this tutorial we'll build a simple application by starting from scratch, adding more -and more pieces over time. Along the way, we'll learn about GtkApplication, -templates, resources, application menus, settings, GtkHeaderBar, GtkStack, -GtkSearchBar, GtkListBox, and more. +and more pieces over time. Along the way, we'll learn about [class@Gtk.Application], +templates, resources, application menus, settings, [class@Gtk.HeaderBar], [class@Gtk.Stack], +[class@Gtk.SearchBar], [class@Gtk.ListBox], and more. -The full, buildable sources for these examples can be found in the `examples/` -directory of the GTK source distribution, or -[online](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples) in the GTK git -repository. You can build each example separately by using make with the -`Makefile.example` file. For more information, see the `README` included in the -examples directory. +The full, buildable sources for these examples can be found in the +`examples` directory of the GTK source distribution, or +[online](https://gitlab.gnome.org/GNOME/gtk/blob/master/examples) in the GTK +source code repository. You can build each example separately by using make +with the `Makefile.example` file. For more information, see the `README` +included in the examples directory. ### A trivial application -When using GtkApplication, the main() function can be very simple. We just call -g_application_run() and give it an instance of our application class. +When using `GtkApplication`, the `main()` function can be very simple. We just call +`g_application_run()` and give it an instance of our application class. -``` {.c source=examples/application1/main.c } +```c #include #include "exampleapp.h" @@ -759,15 +766,15 @@ GtkApplication. Our example does not yet have any interesting functionality. All it does is open a window when it is activated without arguments, and open the files it is given, if it is started with arguments. -To handle these two cases, we override the activate() vfunc, which gets called -when the application is launched without commandline arguments, and the open() -vfunc, which gets called when the application is launched with commandline -arguments. +To handle these two cases, we override the activate() vfunc, which gets +called when the application is launched without commandline arguments, and +the `open()` virtual function, which gets called when the application is +launched with commandline arguments. -To learn more about GApplication entry points, consult the GIO -[documentation](https://developer.gnome.org/gio/2.36/GApplication.html#GApplication.description). +To learn more about `GApplication` entry points, consult the GIO +[documentation](https://developer.gnome.org/gio/stable/GApplication.html#GApplication.description). -``` {.c source=examples/application1/exampleapp.c } +```c #include #include "exampleapp.h" @@ -834,10 +841,10 @@ example_app_new (void) ``` Another important class that is part of the application support in GTK is -GtkApplicationWindow. It is typically subclassed as well. Our subclass does +`GtkApplicationWindow`. It is typically subclassed as well. Our subclass does not do anything yet, so we will just get an empty window. -``` {.c source=examples/application1/examplewin.c } +```c #include #include "exampleapp.h" @@ -878,7 +885,7 @@ create an icon and a desktop file. ![An icon](exampleapp.png) -``` { source=examples/application1/org.gtk.exampleapp.desktop } +``` [Desktop Entry] Type=Application Name=Example @@ -906,7 +913,7 @@ GtkBuilder ui file with our application window class. Our simple ui file gives the window a title, and puts a GtkStack widget as the main content. -``` { .xml source=examples/application2/window.ui } +```xml